﻿using System.Linq;
using CommonBehaviors.Actions;
using Portal.Core;
using Portal.Helpers;
using Portal.Managers;
using Portal.Settings;
using JetBrains.Annotations;
using Styx;
using Styx.CommonBot;
using Styx.TreeSharp;
using Styx.WoWInternals.WoWObjects;
using Action = Styx.TreeSharp.Action;

namespace Portal.Specialisation
{
    [UsedImplicitly]
    internal class Arcane : RotationBase
    {

        #region RotationBase Overrides
        public override WoWSpec KeySpec { get { return WoWSpec.MageArcane; } }
        public override string Name { get { return "Arcane"; } }
        #endregion
        private static PortalSettings Settings { get { return PortalSettings.Instance; } }

        #region Honorbuddy's Rotation Overrides
        public override Composite Rotation
        {
            get
            {
                return new PrioritySelector(
                    new Decorator(ret => Me.CurrentTarget.HasDoNotDamageAura() || Me.HasAura("Ice Block"), new ActionAlwaysSucceed()),

                    Common.NonGcdCombat(),

                    new Decorator(ret => Me.IsChanneling || Me.IsCasting || Common.LoSCheck, new ActionAlwaysSucceed()),

                    Common.SetCounts, // Set counts for our AoE trigger
                    Common.Combat(), // Handles all of our utility / talent abilities.

                    Spell.Cast("Arcane Power", ret => NeedArcanePower),

                    Spell.PreventDoubleCast("Alter Time", 6.5, on => Me, ret => NeedAlterTimeOffensive),

                    // AoE selector
                    new Decorator(ret => Settings.Arcane_EnableAoE && Common._nearbyAoEUnitCount >= Settings.Arcane_AoEUnitCount, HandleAoECombat()),
                    HandleSingleTarget());
            }

        }


        private static Composite HandleSingleTarget()
        {
            return new PrioritySelector(
                Spell.Cast("Arcane Barrage", ret => Me.HasAura("Alter Time") && Spell.GetMyAuraTimeLeft("Alter Time", Me) < 2),
                Spell.Cast("Arcane Missiles", ret => Me.HasAura("Alter Time")),
                Spell.Cast("Arcane Blast", ret => Me.HasAura("Alter Time")),
                Spell.Cast("Arcane Missiles", ret => (Spell.StackCount(Me, "Arcane Missiles!") == 2 && Spell.SpellOnCooldown("Arcane Power")) || (Spell.StackCount(Me, "Arcane Charge") >= 4 && Spell.GetSpellCooldown("Arcane Power").TotalSeconds > 8)),
                Common.HandleSingleTargetMageBombs(),
                new Decorator(ret => Settings.Arcane_EnableAoE, Common.HandleBombMultiDoT()),
                Spell.Cast("Arcane Barrage", ret => Spell.StackCount(Me, "Arcane Charge") >= 4 && Me.ManaPercent < 95),
                Spell.Cast("Presence of Mind", on => Me, ret => NeedPresenceOfMindOffensive),
                Spell.Cast("Arcane Blast"),
                Spell.CastIgnoreMoving("Arcane Barrage", on => Me.CurrentTarget, ret => Me.IsMoving()),
                Spell.CastIgnoreMoving("Fire Blast", on => Me.CurrentTarget, ret => Me.IsMoving()),
                Spell.CastIgnoreMoving("Ice Lance", on => Me.CurrentTarget, ret => Me.IsMoving())
                );
        }

        private static Composite HandleAoECombat()
        {
            return new PrioritySelector(
                Spell.CastOnGround("Flamestrike", on => Me.CurrentTarget.Location, ret => true),
                Common.HandleBombMultiDoT(),
                Spell.Cast("Arcane Barrage", ret => Spell.StackCount(Me, "Arcane Charge") >= 4),
                Spell.Cast("Arcane Explosion", ret => Unit.NearbyAttackableUnits(Me.Location, ArcaneExplosionRadius).Count() >= 6),
                HandleSingleTarget()
                );
        }

        public override Composite PreCombat
        {
            get
            {
                return new PrioritySelector(
                    Common.PreCombat()
                    );
            }
        }

        #endregion

        #region Conditions
        private static bool NeedPresenceOfMindOffensive
        {
            get
            {
                return Settings.UsePresenceOfMind && Settings.PresenceOfMindCondition == 4 && TalentManager.HasTalent(1);
            }
        }

        private static bool NeedAlterTimeOffensive
        {
            get
            {
                return Settings.UseAlterTimeOffensive && Me.HasAura("Arcane Power");
            }
        }

        private static int ArcaneExplosionRadius
        {
            get
            {
                if (TalentManager.HasGlyph("Arcane Explosion"))
                {
                    return 15;
                }

                return 10;
            }
        }

        private static bool CanSlow
        {
            get
            {
                return Unit.NearbyAttackableUnits(Me.Location, 60).Count(u => u.HasAura("Slow")) == 0;
            }
        }

        private static bool NeedArcanePower
        {
            get
            {
                //Never
                if (Settings.Arcane_ArcanePowerCondition == 0)
                {
                    return false;
                }

                var needPower = Spell.StackCount(Me, "Arcane Missiles!") >= 2 &&
                                Spell.StackCount(Me, "Arcane Charge") >= 3;

                if (!needPower)
                {
                    return false;
                }

                //On Cooldown
                if (Settings.Arcane_ArcanePowerCondition == 1)
                {
                    return true;
                }

                //On Boss Or Player
                if (Settings.Arcane_ArcanePowerCondition == 2 && Me.CurrentTarget.IsBossOrPlayer())
                {
                    return true;
                }

                //On Target Low HP
                if (Settings.Arcane_ArcanePowerCondition == 3 && Me.CurrentTarget.HealthPercent <= Settings.Arcane_ArcanePowerLowHPValue)
                {
                    return true;
                }

                return false;
            }
        }
        #endregion

        #region Units

        #endregion

    }
}
